using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;

namespace Irc.Objects
{
	[CLSCompliant(true)]
	public abstract class Target
	{
		public abstract override string ToString();
	}
	public abstract class ClientEvent
	{
		private DateTime time;
		private Target target;
		public DateTime Time
		{
			get { return time; }
			set { time = value; }
		}
		public Target Target
		{
			get { return target; }
			set { target = value; }
		}
	}
	public abstract class ChannelEvent : ClientEvent
	{
	}
	public abstract class UserEvent : ClientEvent
	{
	}
	public abstract class ConnectionEvent : ClientEvent
	{
	}
	public abstract class ServerEvent : ClientEvent
	{
	}

	[CLSCompliant(true)]
	public class Message : ConnectionEvent
	{
		private Target sender;
		private string message;
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
		public string Text
		{
			get { return message; }
			set { message = value; }
		}
	}
	[CLSCompliant(true)]
	public class Ctcp : Message
	{
		private string parameters;
		public string Parameters
		{
			get { return parameters; }
			set { parameters = value; }
		}
	}
	[CLSCompliant(true)]
	public class PublicMessage : Message
	{
	}
	[CLSCompliant(true)]
	public class PrivateMessage : Message
	{
	}
	[CLSCompliant(true)]
	public class ServerMessage : Message
	{
	}
	[CLSCompliant(true)]
	public class PublicNotice : Message
	{
	}
	[CLSCompliant(true)]
	public class PrivateNotice : Message
	{
	}
	[CLSCompliant(true)]
	public class ServerNotice : Message
	{
	}
	[CLSCompliant(true)]
	public class PublicAction : Message
	{
	}
	[CLSCompliant(true)]
	public class PrivateAction : Message
	{
	}
	[CLSCompliant(true)]
	public class Nicklist : ChannelEvent
	{
		private List<Nickname> nicks = new List<Nickname>();
		public Collection<Nickname> Nicknames
		{
			get { return new Collection<Nickname>(nicks); }
			internal set
			{
				lock(this)
				{
					nicks.Clear();
					nicks.AddRange(value);
				}
			}
		}
	}
	[CLSCompliant(true)]
	public class Motd : ServerEvent
	{
		private string motd;
		public string Message
		{
			get { return motd; }
			internal set { motd = value; }
		}
	}
	[CLSCompliant(true)]
	public class Topic : ChannelEvent
	{
		private Nickname sender;
		private string text;
		public Nickname Sender
		{
			get { return sender; }
			set { sender = value; }
		}
		public string Text
		{
			get { return text; }
			set { text = value; }
		}
	}
	[CLSCompliant(true)]
	public interface IModeMessage
	{
		Target Sender { get; set; }
		Mode Mode { get; set; }
		DateTime Time { get; set; }
	}
	[CLSCompliant(true)]
	public interface IModeAdd : IModeMessage
	{
	}
	[CLSCompliant(true)]
	public interface IModeRemove : IModeMessage
	{
	}
	[CLSCompliant(true)]
	public class ChannelModeAdd : ChannelEvent, IModeMessage, IModeAdd
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	[CLSCompliant(true)]
	public class NickModeAdd : UserEvent, IModeMessage, IModeAdd
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	[CLSCompliant(true)]
	public class ServerModeAdd : ServerEvent, IModeMessage, IModeAdd
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	[CLSCompliant(true)]
	public class ChannelModeRemove : ChannelEvent, IModeMessage, IModeRemove
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	[CLSCompliant(true)]
	public class NickModeRemove : UserEvent, IModeMessage, IModeRemove
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	[CLSCompliant(true)]
	public class ServerModeRemove : ServerEvent, IModeMessage, IModeRemove
	{
		private Mode mode;
		private Target sender;
		public Mode Mode
		{
			get { return mode; }
			set { mode = value; }
		}
		public Target Sender
		{
			get { return sender; }
			set { sender = value; }
		}
	}
	// TODO: Rename this crappily named class
	[CLSCompliant(true)]
	public class UserMove : ChannelEvent
	{
		private Nickname user;
		public Nickname User
		{
			get { return user; }
			internal set { user = value; }
		}
	}
	[CLSCompliant(true)]
	public class UserJoin : UserMove
	{
	}
	[CLSCompliant(true)]
	public class UserPart : UserMove
	{
	}
}
